package trader

import (
	"fmt"
	"nofx/market"
	"time"
)

// PriceQuote 统一的报价结构（适配各交易所/数据源）
type PriceQuote struct {
	Symbol     string    `json:"symbol"`
	Price      float64   `json:"price"`
	Exchange   string    `json:"exchange"`
	IsTestnet  bool      `json:"is_testnet"`
	Source     string    `json:"source"` // ticker_ws | exchange_api | hl_all_mids
	Timestamp  time.Time `json:"timestamp"`
}

// PriceProviderOptions 价格提供者配置
type PriceProviderOptions struct {
	HTTPProxy string
	IsTestnet bool
}

// PriceProvider 报价接口（策略/适配器）
type PriceProvider interface {
	GetQuote(symbol string) (*PriceQuote, error)
}

// TraderPriceProvider 通用适配器：通过 Trader 接口获取价格
type TraderPriceProvider struct {
	trader   Trader
	exchange string
	opts     PriceProviderOptions
}

func (p *TraderPriceProvider) GetQuote(symbol string) (*PriceQuote, error) {
	norm := market.Normalize(symbol)
	price, err := p.trader.GetMarketPrice(norm)
	if err != nil {
		return nil, err
	}
	if price <= 0 {
		return nil, fmt.Errorf("价格无效: %.8f", price)
	}
	source := "exchange_api"
	if p.exchange == "hyperliquid" {
		source = "hl_all_mids"
	}
	return &PriceQuote{
		Symbol:    norm,
		Price:     price,
		Exchange:  p.exchange,
		IsTestnet: p.opts.IsTestnet,
		Source:    source,
		Timestamp: time.Now(),
	}, nil
}

// BinancePriceProvider 币安适配器：优先使用 WS ticker，失败回退到 HTTP ticker
// 注：当前 WS Monitor 固定连接主网；如需测试网，可扩展为独立 WS 客户端。
type BinancePriceProvider struct {
	trader   Trader
	opts     PriceProviderOptions
}

func (p *BinancePriceProvider) GetQuote(symbol string) (*PriceQuote, error) {
	norm := market.Normalize(symbol)

	var price float64
	var source string

	// 优先用全局 WSMonitor 的 ticker 价（仅主网）
	if market.WSMonitorCli != nil && !p.opts.IsTestnet {
		if tp, err := market.WSMonitorCli.GetTickerPrice(norm); err == nil && tp > 0 {
			price = tp
			source = "ticker_ws"
		}
	}

	// 回退：使用交易器的 GetMarketPrice 或 HTTP API
	if price <= 0 {
		// 优先用交易器（SDK）以保持与下单交易所一致
		if p.trader != nil {
			if tp, err := p.trader.GetMarketPrice(norm); err == nil && tp > 0 {
				price = tp
				source = "exchange_api"
			}
		}
	}

	if price <= 0 {
		api := market.NewAPIClientWithTestnet(p.opts.HTTPProxy, p.opts.IsTestnet)
		if tp, err := api.GetCurrentPrice(norm); err == nil && tp > 0 {
			price = tp
			source = "exchange_api"
		}
	}

	if price <= 0 {
		return nil, fmt.Errorf("无法获取 %s 价格", norm)
	}

	return &PriceQuote{
		Symbol:    norm,
		Price:     price,
		Exchange:  "binance",
		IsTestnet: p.opts.IsTestnet,
		Source:    source,
		Timestamp: time.Now(),
	}, nil
}

// NewPriceProvider 工厂：按交易所返回对应价格适配器
func NewPriceProvider(exchange string, trader Trader, opts PriceProviderOptions) PriceProvider {
	switch exchange {
	case "binance":
		return &BinancePriceProvider{trader: trader, opts: opts}
	case "hyperliquid":
		return &TraderPriceProvider{trader: trader, exchange: exchange, opts: opts}
	case "aster":
		return &TraderPriceProvider{trader: trader, exchange: exchange, opts: opts}
	default:
		return &TraderPriceProvider{trader: trader, exchange: exchange, opts: opts}
	}
}